<?php
/*
 * This scaffolding is designed by Xrvel
 * http://www.xrvel.com/
 */

class m_xrvel_scaffolding extends Model {
	function m_xrvel_scaffolding() {
		parent::Model();
	}

	function add($table_name, $on_success = '') {
		$xs_config = $this->config->item('xrvel_scaffolding');

		$xs_config = $xs_config[$table_name];
		$primary_key = xrvel_scaffolding_get_primary_key($xs_config);

		$return = xrvel_scaffolding_parse_info(array(
			'mode' => 'edit',
			'table_name' => $table_name,
			'config' => $xs_config
		));

		$select = $return['select'];
		$column_info = $return['column_info'];
		$column_names = $return['column_names'];
		$join = $return['join'];
		$xs_config = $return['config'];

		$load_data = array();
		$keys = array_keys($column_info);
		foreach ($keys as $k) {
			$load_data[$k] = '';
		}
		unset($keys);

		// Prepare view
		$view_data = $this->m_xrvel_scaffolding_var->item('view_data', array());
		$view_template = $this->m_xrvel_scaffolding_var->item('view_template');
		if ($view_template === false) {
			show_error('View template is not defined');
			return true;
		}
		$view_data['load_data'] = $load_data;
		$view_data['xs_config'] = $xs_config;// Pass config

		$view_data['xs_primary_key'] = xrvel_scaffolding_get_primary_key($xs_config);
		$view_data['xs_column_info'] = $column_info;

		$this->load->library('form_validation');

		if ($load_data != array()) {
			$cols = array();
			$hidden = array();
			foreach ($load_data as $name=>$value) {
				$proceed = true;
				if (isset($column_info[$name]['additional_join'])) {
					$proceed = false;
				} else if (isset($column_info[$name]['primary_key']) && $column_info[$name]['primary_key'] === true) {
					$proceed = false;
				} else if (isset($column_info[$name]['editable']) && $column_info[$name]['editable'] === false) {
					$proceed = false;
				} else if (isset($column_info[$name]['hide_on']) && is_array($column_info[$name]['hide_on'])) {
					if (in_array('add', $column_info[$name]['hide_on'])) {
						$hidden[] = $name;
						$proceed = false;
					}
				}
				if ($proceed) {
					$cols[] = $name;
				}
			}
			$array_of_data = array();
			$this->form_validation->set_error_delimiters('<div class="xrvel_scaffolding_error">', '</div>');
			foreach ($cols as $name) {
				$rule = 'trim';
				if (isset($column_info[$name]['ci_rule'])) {
					$rule = $column_info[$name]['ci_rule'];
				}
				$this->form_validation->set_rules($name, $column_info[$name]['friendly_name'], $rule);
				$array_of_data[$name] = trim($this->input->post($name, ''));
			}
			if ($this->form_validation->run() == false) {
				if ($this->input->post('go') !== false) {
					$view_data['error_message'] = XS_DATA_EMPTY;
				}
			} else {
				if ($hidden != array()) {
					foreach ($hidden as $name) {
						if (isset($column_info[$name]['on_add'])) {
							$on_func = $column_info[$name]['on_add'];
							if (strpos($on_func, '|') === false) {
								$array_of_data[$name] = call_user_func($on_func);
							} else {
								list($func_1, $func_2) = explode('|', $on_func);
								$on_func_arg = false;
								if (preg_match('/xrvel_scaffolding_var\[([a-z0-9\_\-]+)\]/i', $func_2, $match)) {
									$on_func_arg = $this->m_xrvel_scaffolding_var->item($match[1]);
								}
								$array_of_data[$name] = call_user_func($func_1, $on_func_arg);
							}
						}
					}
				}
				if ($data_id = $this->m_xrvel_scaffolding->add_single($table_name, $array_of_data)) {
					$view_data['ok_message'] = XS_DATA_ADD_OK;
				} else {
					$view_data['error_message'] = XS_DATA_ADD_ERROR;
				}
				if ($this->config->item('xrvel_scaffolding_print_query') === true) {
					xrvel_scaffolding_print_query($this->db->last_query());
				}
			}
		}

		if (isset($xs_config['friendly_name'])) {
			$view_data['xs_friendly_name'] = $xs_config['friendly_name'];
		} else {
			$view_data['xs_friendly_name'] = xrvel_scaffolding_friendly_name($table_name);
		}

		if ($this->session->flashdata('xs_error_message') !== false) {
			$view_data['error_message'] = $this->session->flashdata('xs_error_message');
		}

		if ($this->session->flashdata('xs_ok_message') !== false) {
			$view_data['ok_message'] = $this->session->flashdata('xs_ok_message');
		}

		// First view
		$xrvel_scaffolding_view = $this->load->view('xrvel_scaffolding/add', $view_data, true);

		// Main view
		$view_data['xrvel_scaffolding_view'] = $xrvel_scaffolding_view;
		$this->load->view($view_template, $view_data);
	}

	function add_single($table_name, $data) {
		$this->db->insert($table_name, $data); 
		return $this->db->insert_id();
	}

	// Delete single data
	function delete($table_name, $data_id, $on_success = '') {
		$xs_config = $this->config->item('xrvel_scaffolding');

		$xs_config = $xs_config[$table_name];
		$primary_key = xrvel_scaffolding_get_primary_key($xs_config);
		$load_data = $this->m_xrvel_scaffolding->get_single($table_name, $primary_key, $data_id);

		$return = xrvel_scaffolding_parse_info(array(
			'mode' => 'edit',
			'table_name' => $table_name,
			'config' => $xs_config
		));
		$select = $return['select'];
		$column_info = $return['column_info'];
		$column_names = $return['column_names'];
		$join = $return['join'];
		$xs_config = $return['config'];

		if ($this->db->delete($table_name, array($primary_key => $data_id))) {
			$this->session->set_flashdata('xs_ok_message', XS_DATA_DELETE_OK);
		} else {
			$this->session->set_flashdata('xs_error_message', XS_DATA_DELETE_ERROR);
		}
		if ($on_success == '') {
			$on_success = 'index.php/'.$this->uri->segment(1).'/view/';
		}
		redirect($on_success);
	}

	// Edit single data
	function edit($table_name, $data_id, $on_success = '') {
		$xs_config = $this->config->item('xrvel_scaffolding');

		$xs_config = $xs_config[$table_name];
		$primary_key = xrvel_scaffolding_get_primary_key($xs_config);

		$return = xrvel_scaffolding_parse_info(array(
			'mode' => 'edit',
			'table_name' => $table_name,
			'config' => $xs_config
		));
		$select = $return['select'];
		$column_info = $return['column_info'];
		$column_names = $return['column_names'];
		$join = $return['join'];
		$xs_config = $return['config'];

		$load_data = $this->m_xrvel_scaffolding->get_single($table_name, $primary_key, $data_id);

		// Prepare view
		$view_data = $this->m_xrvel_scaffolding_var->item('view_data', array());
		$view_template = $this->m_xrvel_scaffolding_var->item('view_template');
		if ($view_template === false) {
			show_error('View template is not defined');
			return true;
		}
		$view_data['load_data'] = $load_data;
		$view_data['xs_config'] = $xs_config;// Pass config

		$view_data['xs_primary_key'] = xrvel_scaffolding_get_primary_key($xs_config);
		$view_data['xs_column_info'] = $column_info;

		$this->load->library('form_validation');

		if ($load_data != array()) {
			$cols = array();
			$hidden = array();
			foreach ($load_data as $name=>$value) {
				$proceed = true;
				if (isset($column_info[$name]['primary_key']) && $column_info[$name]['primary_key'] === true) {
					$proceed = false;
				} else if (isset($column_info[$name]['editable']) && $column_info[$name]['editable'] === false) {
					$proceed = false;
				} else if (isset($column_info[$name]['hide_on']) && is_array($column_info[$name]['hide_on'])) {
					if (in_array('edit', $column_info[$name]['hide_on'])) {
						$hidden[] = $name;
						$proceed = false;
					}
				}
				if ($proceed) {
					$cols[] = $name;
				}
			}
			$array_of_data = array();
			$this->form_validation->set_error_delimiters('<div class="xrvel_scaffolding_error">', '</div>');
			foreach ($cols as $name) {
				$rule = 'trim';
				if (isset($column_info[$name]['ci_rule'])) {
					$rule = $column_info[$name]['ci_rule'];
				}
				$this->form_validation->set_rules($name, $column_info[$name]['friendly_name'], $rule);
				$array_of_data[$name] = trim($this->input->post($name, ''));
			}
			if ($this->form_validation->run() == false) {
				if ($this->input->post('go') !== false) {
					$view_data['error_message'] = XS_DATA_EMPTY;
				}
			} else {
				if ($hidden != array()) {
					foreach ($hidden as $name) {
						if (isset($column_info[$name]['on_edit'])) {
							$on_func = $column_info[$name]['on_edit'];
							if (strpos($on_func, '|') === false) {
								$array_of_data[$name] = call_user_func($on_func);
							} else {
								list($func_1, $func_2) = explode('|', $on_func);
								$on_func_arg = false;
								if (preg_match('/xrvel_scaffolding_var\[([a-z0-9\_\-]+)\]/i', $func_2, $match)) {
									$on_func_arg = $this->m_xrvel_scaffolding_var->item($match[1]);
								}
								$array_of_data[$name] = call_user_func($func_1, $on_func_arg);
							}
						}
					}
				}
				$where = array(
					$primary_key => $data_id
				);
				if ($this->m_xrvel_scaffolding->edit_single($table_name, $array_of_data, $where)) {
					if ($on_success == '') {
						$on_success = current_url();
					}
					$this->session->set_flashdata('xs_ok_message', XS_DATA_EDIT_OK);
					redirect($on_success);
					return true;
				} else {
					$view_data['error_message'] = XS_DATA_EDIT_ERROR;
				}
				if ($this->config->item('xrvel_scaffolding_print_query') === true) {
					xrvel_scaffolding_print_query($this->db->last_query());
				}
				$load_data = $this->m_xrvel_scaffolding->get_single($table_name, $primary_key, $data_id);
				$view_data['load_data'] = $load_data;
			}
		}

		if (isset($xs_config['friendly_name'])) {
			$view_data['xs_friendly_name'] = $xs_config['friendly_name'];
		} else {
			$view_data['xs_friendly_name'] = xrvel_scaffolding_friendly_name($table_name);
		}

		if ($this->session->flashdata('xs_error_message') !== false) {
			$view_data['error_message'] = $this->session->flashdata('xs_error_message');
		}

		if ($this->session->flashdata('xs_ok_message') !== false) {
			$view_data['ok_message'] = $this->session->flashdata('xs_ok_message');
		}

		// First view
		$xrvel_scaffolding_view = $this->load->view('xrvel_scaffolding/edit', $view_data, true);

		// Main view
		$view_data['xrvel_scaffolding_view'] = $xrvel_scaffolding_view;
		$this->load->view($view_template, $view_data);
	}

	function edit_single($table_name, $data, $where) {
		$this->db->update($table_name, $data, $where);
		return true;
	}

	// Load single data
	function get_single($table_name, $data_column, $data_id) {
		$q = "SELECT * FROM $table_name WHERE $data_column = $data_id";
		if ($this->config->item('xrvel_scaffolding_print_query') === true) {
			xrvel_scaffolding_print_query($q);
		}
		$q = $this->db->query($q);
		$data = array();
		if ($q->num_rows() > 0) {
			$data = $q->row_array();
		}
		return $data;
	}

	// View all data
	function view($table_name) {
		$xs_config = $this->config->item('xrvel_scaffolding');

		$xs_config = $xs_config[$table_name];

		$return = xrvel_scaffolding_parse_info(array(
			'mode' => 'view',
			'table_name' => $table_name,
			'config' => $xs_config
		));
		$select = $return['select'];
		$column_info = $return['column_info'];
		$column_names = $return['column_names'];
		$join = $return['join'];

		// Everything is completed, prepare the query
		$order_by = '';
		if (isset($xs_config['order_by'])) {
			$order_by = implode(",\r\n\t", $xs_config['order_by']);
		}

		$q = "SELECT\r\n\t".implode(",\r\n\t", $select)."\r\nFROM\r\n\t$table_name\r\n";
		if ($join != array()) {
			$q .= implode(" \r\n", $join);
		}
		if ($order_by != '') {
			$q .= "\r\nORDER BY\r\n\t$order_by";
		}
		$q = trim($q);
		if ($this->config->item('xrvel_scaffolding_print_query') === true) {
			xrvel_scaffolding_print_query($q);
		}

		$q = $this->db->query($q);
		$data = array();
		foreach ($q->result_array() as $r) {
			$data[] = $r;
		}

		// Prepare view
		$view_data = $this->m_xrvel_scaffolding_var->item('view_data', array());
		$view_template = $this->m_xrvel_scaffolding_var->item('view_template');
		if ($view_template === false) {
			show_error('View template is not defined');
			return true;
		}
		$view_data['xs_config'] = $xs_config;// Pass config

		$view_data['xs_primary_key'] = xrvel_scaffolding_get_primary_key($xs_config);
		$view_data['xs_column_info'] = $column_info;
		$view_data['xs_view_columns'] = $column_names;

		if (isset($xs_config['friendly_name'])) {
			$view_data['xs_friendly_name'] = $xs_config['friendly_name'];
		} else {
			$view_data['xs_friendly_name'] = xrvel_scaffolding_friendly_name($table_name);
		}
		$view_data['load_data'] = $data;

		if ($this->session->flashdata('xs_error_message') !== false) {
			$view_data['error_message'] = $this->session->flashdata('xs_error_message');
		}

		if ($this->session->flashdata('xs_ok_message') !== false) {
			$view_data['ok_message'] = $this->session->flashdata('xs_ok_message');
		}

		// First view
		$xrvel_scaffolding_view = $this->load->view('xrvel_scaffolding/view', $view_data, true);

		// Main view
		$view_data['xrvel_scaffolding_view'] = $xrvel_scaffolding_view;
		$this->load->view($view_template, $view_data);
	}
}
?>